package com.red.battleworm.model {
	import flash.ui.Keyboard;	
	import flash.events.MouseEvent;	
	import flash.events.KeyboardEvent;	
	
	import com.red.battleworm.map.Map;	
	import com.red.battleworm.element.*;	
	import com.red.battleworm.AppMain;	
	
	import org.puremvc.as3.patterns.proxy.Proxy;

	import flash.display.Loader;	
	import flash.display.DisplayObjectContainer;	
	import flash.net.URLRequest;
	import flash.events.IOErrorEvent;
	import flash.events.Event;
	import flash.events.ProgressEvent;

	import org.cove.ape.*;

	/**
	 * @author zhangs
	 */
	public class GameProxy extends Proxy {
		private var loader : Loader;
		private var map : Map;
		private var player : Player;
		private var bullet_list : Array;
		
		public function GameProxy(proxyName : String) {
			super(proxyName, null);
		}
		
		public function loadMap(map_id : String, map_url : String) : void {
			if (facade.hasProxy(map_id)) {
				start(map_id);
				return;
			}
			
			var aURLRequest : URLRequest = new URLRequest(map_url);
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, 	function (e : Event) : void {
																			completeHandler(e, map_id);
																		});
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			loader.load(aURLRequest);
		}

		private function completeHandler(event:Event, map_id : String):void {
            trace("completeHandler: " + event);
            var map : Object = event.target.content;
			facade.registerProxy(new MapProxy(map_id, map));
			start(map_id);
		}

		private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
        }
        
        private function progressHandler(event:ProgressEvent):void {
            trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
        }
        
        private function start(map_id : String) : void {
			bullet_list = new Array();
			var aMapProxy : MapProxy = MapProxy(facade.retrieveProxy(map_id));
			map = aMapProxy.getMap();
			
			APEngine.init(1/4);
			
			// set up the default diplay container
			APEngine.container = DisplayObjectContainer(AppMain.stage);
			
			// gravity -- particles of varying masses are affected the same
			APEngine.addForce(new VectorForce(false, 0, 10));
			
			// groups - all these classes extend group
			APEngine.addGroup(map);
			
			var birth_array : Array = map.birth_array;
			var birth : Object = birth_array[uint(Math.random() * birth_array.length)];
			player = new Player(birth);
			APEngine.addGroup(player);
			
			player.addCollidable(aMapProxy.getBound());
			player.addCollidable(map);
			
			AppMain.stage.addEventListener(Event.ENTER_FRAME, run);
			AppMain.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandle);
			AppMain.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandle);
			AppMain.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
			AppMain.stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandle);
        }
        
        private function run(evt:Event):void {
			player.run();
			for each (var bullet : Bullet in bullet_list) {
				bullet.run();
			}
			checkCollision();
			APEngine.step();
			APEngine.paint();
		}
		
		private function checkCollision() : void {
			for each (var bullet : Bullet in bullet_list) {
				if (SpecialCollisionDetector.test(bullet.body, player.body)) {
					trace(bullet);
				}
			}
		}
        
        private function keyDownHandle(evt : KeyboardEvent) : void {
//        	trace(evt);
        	switch(evt.keyCode) {
        		case Keyboard.LEFT:
        			player.setSpeed(Player.LEFTSPEED);
					break;
        		case Keyboard.RIGHT:
					player.setSpeed(Player.RIGHTSPEED);
					break;
				default:
//					player.playActions();
        	}
        }
        
        private function keyUpHandle(evt : KeyboardEvent) : void {
			player.setSpeed(AbstractElement.NONESPEED);
        }
        
        private function mouseMoveHandle(evt : MouseEvent) : void {
			player.updateArrow(evt);
        }
        
        private function mouseDownHandle(evt : MouseEvent) : void {
//        	trace(evt);
        	var bullet : Bullet = new Bullet(player.body.px, player.body.py, player.arrow_rotation, player.scale);
			bullet.addCollidable(map);
			APEngine.addGroup(bullet);
			
			if (bullet_list.length >= 20) {
				APEngine.removeGroup(bullet_list[0]);
				bullet_list.shift();
			}
			bullet_list.push(bullet);
		}
	}
}